package com.chen.function_demo.chapter3;

import java.util.Comparator;
import java.util.List;

/**
 * 第三章第四节
 * @author 陈哲<p>
 * ================================<p>
 * Date: 2025/5/12<p>
 * Time: 11:10<p>
 * ================================
 */
public class Section4 {
    /*
        其他基础的Stream API：
        1、查找：
        （1）findAny() 查找范围内的任意一个 一般和filter搭配使用 filter(Predicate).findAny()
        （2）findFirst() 查找范围内的第一个 一般和filter搭配使用 filter(Predicate).findFirst()
        2、判断：
        （1）anyMatch(Predicate)  查找范围内是否有满足条件的，有任意一个就返回真
        （2）allMatch(Predicate)  查找范围内是否全部满足条件，全部满足返回真
        （3）noneMatch(Predicate) //查找范围内是否没有满足条件的，都不能满足就返回真
        3、去重：
        （1）distinct()
        4、排序：
        （1）sorted() 搭配Comparator函数使用
        5、化简：
        （1）reduce((p,x) -> r) // p是上次合并的结果，x是当前元素，r是返回值
        （2）reduce(init,(p,x) -> r) // init是初始值，p是上次合并的结果，x是当前元素，r是返回值
        （3）reduce(T, BinaryOperator) //化简流中的元素，返回一个值
         适用于：最大值、最小值、求和、个数等
     */
    public static void main(String[] args) {
        List<Integer> integers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 需求1:找到列表中第一个偶数
        integers.stream() //  构造流
                .filter(x -> (x & 1) == 0) //  筛选偶数
                .findFirst() // 获取第一个 todo Optional各种用法有时间了好好学学
                .ifPresent(System.out::println);
        System.out.println("------------------------------------------------");
        // 需求2:找到列表中任意一个偶数
        integers.stream() //  构造流
                .filter(x -> (x & 1) == 0) //  筛选偶数
                .findFirst() // 获取任意一个
                .ifPresent(System.out::println);
        System.out.println("=================================================");
        //  需求3:判断列表中是否有偶数
        System.out.println(integers.stream().anyMatch(x -> (x & 1) == 0));
        //  需求4:判断列表中是否全是偶数
        System.out.println(integers.stream().allMatch(x -> (x & 1) == 0));
        //  需求5:判断列表中是否没有偶数
        System.out.println(integers.stream().noneMatch(x -> (x & 1) == 0));
        System.out.println("=================================================");
        // 去重：distinct()
        List<Integer> integerList = List.of(1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10);
        integerList.stream()
                .distinct() // 去重 如果元素是对象的话，则会调用对象的equals方法，如果对象没有重写equals方法，则比较内存地址
                .forEach(System.out::println);
        System.out.println("=================================================");
        // 排序：sorted()
        List<Student> students = List.of(new Student("张三", 90), new Student("李四", 90), new Student("王五", 99), new Student("赵六", 80));
        students.stream()
                //.sorted(Comparator.comparingInt(Student::getScore)) // 正序
                //.sorted(Comparator.comparingInt(Student::getScore).reversed())//  倒序
                .sorted(Comparator.comparingInt(Student::score).reversed().thenComparing(s -> s.name().length()))//  倒序 增加第二排序条件thenComparing
                .forEach(System.out::println);
        System.out.println("=================================================");
        List<Student> student2 = List.of(new Student("张三", 90), new Student("李四", 99), new Student("王五", 99), new Student("赵六", 80));
        // 获取成绩最高的学生 reduce((p,x) -> r)
        student2.stream()
                .reduce((s1, s2) -> s1.score() > s2.score() ? s1 : s2)
                .ifPresent(System.out::println);
        // 获取成绩最高的学生 reduce(init, (p,x) -> r) 参数传初始值的返回结果就不是Optional了
        System.out.println(student2.stream()
                .reduce(new Student("-", 0), (s1, s2) -> s1.score() > s2.score() ? s1 : s2));
        System.out.println("=================================================");
        // 计算有多少学生
        System.out.println(student2.stream().reduce(0, (p, x) -> p + 1, Integer::sum));
        // 由reduce方法延伸出来的一些常用方法
        // count() 获取元素个数
        System.out.println(student2.stream().filter((stu) -> stu.score > 80).count());
        // max() 获取最大值 Comparator比较器
        System.out.println(student2.stream().max(Comparator.comparingInt(Student::score)));
        // min() 获取最小值
        System.out.println(student2.stream().min(Comparator.comparingInt(Student::score)));
        // sum() 求和
        System.out.println(student2.stream().mapToInt(Student::score).sum());
        // average() 求平均值
        System.out.println(student2.stream().mapToInt(Student::score).average());
    }

    record Student(String name, int score) {}
}
